#include "ThreadPool.hpp"
#include "Thread.hpp"

#include <unistd.h>
/* #include <iostream> */
namespace xkk
{


ThreadPool::ThreadPool(size_t threadNum,size_t queSize)
    :_threadNum(threadNum)
     ,_queSize(queSize)
     ,_threads()
     ,_taskQue(_queSize)
     ,_isExit(false)
    {
        _threads.reserve(_threadNum);
    }

ThreadPool::~ThreadPool()
{
    if(!_isExit){
        stop();
    }
}

void ThreadPool::start()
{
    /* cout<<"ThreadPool start!"<<endl; */
    for(size_t idx=0;idx!=_threadNum;idx++)
    {
        unique_ptr<Thread> up(new Thread(
                bind(&ThreadPool::threadFunc,this),to_string(idx)));
        _threads.push_back(std::move(up));        
    }

    for(auto &thread:_threads)
    {
        thread->start();
    }
}

void ThreadPool::addTask(Task &&task)
{
    /* cout<<"addTask"<<endl; */
    _taskQue.push(task);
}

Task ThreadPool::getTask()
{
    return _taskQue.pop();
}

void ThreadPool::stop()
{
    if(!_isExit)
    {
        while(!_taskQue.empty())
        {
            ::sleep(2);
        }
        _isExit=true;
        _taskQue.wakeup();
        for(auto &thread:_threads)
        {
            thread->join();
        }
    }
}

void ThreadPool::threadFunc()
{
    while(!_isExit){
        Task task=getTask();
        if(task)
            task();
    }
}

}//end of namespace xkk
